#include <iostream>
#include <unistd.h>
#include <assert.h>
#include <string>
#include <cstdio>
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

//因为有写实拷贝的存在，无法更改通信，所以不能定义全局的buffer来进行通信

int main()
{
    //1.创建管道
    int pipefd[2] = {0};//pipefd[0]:读端,pipefd[1]:写端
    int n = pipe(pipefd);
    assert(n != -1);
    (void)n;

#ifdef DEBUG
    cout << "pipefd[0]:" << pipefd[0] << endl; //3
    cout << "pipefd[1]:" << pipefd[1] << endl; //4
#endif

    //2.创建子进程
    pid_t id = fork();
    assert(id >= 0);
    if (id == 0)
    {
        //子进程 - 读
        //3.建立单向通信的信道，父进程写入，子进程读取
        //3.1 关闭子进程不需要的fd
        close(pipefd[1]);

        char buffer[1024];
        while (true)
        {
            //写入的一方，fd没有关闭，如果有数据就读，没有数据就等
            //写入的一方，fd关闭了，读取的一方read会返回0，表示读到了文件的结尾
            ssize_t s = read(pipefd[0], buffer, sizeof(buffer) - 1);
            if (s > 0)
            {
                buffer[s] = 0;
                cout << "child get a message[" << getpid() << "]" << "Father# " << buffer << endl;
            }
            else if (s == 0)
            {
                cout << "writer quit(father), me quit!!!" << endl;
                break;
            }

        }

        close(pipefd[0]);
        exit(0);
    }

    //父进程 - 写
    //3.建立单向通信的信道，父进程写入，子进程读取
    //3.1 关闭子进程不需要的fd
    close(pipefd[0]);

    string message = "我是父进程，我正在给你发送消息";
    int count = 0;
    char send_buffer[1024];

    while (true)
    {
        //3.2构建一个变化的字符串
        snprintf(send_buffer, sizeof(send_buffer), "%s[%d]:%d", message.c_str(), getpid(), count++);
        //3.3写入
        write(pipefd[1], send_buffer, sizeof(send_buffer) - 1);
        //3.4故意sleep
        sleep(1);

        cout << count << endl;
        if (count == 5)
        {
            cout << "writer quit(father)" << endl;
            break;
        }
    }

    close(pipefd[1]);

    pid_t ret = waitpid(id, nullptr, 0);
    assert(ret > 0);
    (void)ret;

    return 0;
}